package com.shu.course

import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import retrofit2.Call
import retrofit2.Callback
import retrofit2.HttpException
import retrofit2.Response
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

private const val TAG = "CourseViewModel"

class CourseViewModel : ViewModel() {
    var userList by mutableStateOf(listOf<User>())

    fun search(q: String) {
//        协程方式
//        viewModelScope.launch {
//            try {
//                val users = GiteeApi.create().search(q, 1, 20)
//                if (users.isNotEmpty()) {
//                    withContext(Dispatchers.Main) {
//                        userList = users
//                    }
//                }
//            } catch (e: Exception) {
//                Log.e(TAG, "search: ${e}")
//            }
//        }
//      Rxjava方式
//        GiteeApi.create().search(q,1,20)
//            .subscribeOn(Schedulers.io())
//            .observeOn(AndroidSchedulers.mainThread())
//            .subscribe { users ->
//                userList = users
//            }

//        自封装写法
        viewModelScope.launch {
//            val users = requestAwait { GiteeApi.create().search(q, 1, 20) }
            val users = suspendSearch(q)
            withContext(Dispatchers.Main) {
                userList = users
            }
        }
    }

    suspend fun suspendSearch(q: String) = suspendCoroutine<List<User>> { continuation ->
        GiteeApi.create().search(q, 1, 20).enqueue(object : Callback<List<User>> {
            override fun onResponse(call: Call<List<User>>, response: Response<List<User>>) {
                if (response.isSuccessful) {
                    response.body()?.let { continuation::resume }
                        ?: continuation.resumeWithException(NullPointerException())
                } else {
                    continuation.resumeWithException(HttpException(response))
                }
            }

            override fun onFailure(call: Call<List<User>>, t: Throwable) {
                continuation.resumeWithException(t)
            }
        })
    }

    suspend fun <T> requestAwait(block: () -> Call<T>) = suspendCoroutine<T> { continuation ->
        val call = block();
        call.enqueue(object : Callback<T> {
            override fun onResponse(call: Call<T>, response: Response<T>) {
                if (response.isSuccessful) {
                    response.body()?.let { continuation::resume }
                        ?: continuation.resumeWithException(NullPointerException())
                } else {
                    continuation.resumeWithException(HttpException(response))
                }
            }

            override fun onFailure(call: Call<T>, t: Throwable) {
                continuation.resumeWithException(t)
            }
        })
    }
}